package com.xiaoa.gossip.cluster.service;

import com.xiaoa.gossip.cluster.command.NodeState;
import com.xiaoa.gossip.cluster.command.PingCommand;
import com.xiaoa.gossip.cluster.command.PingNodeState;

import java.util.List;

/**
 * 集群服务
 *
 * @author luokaichuang
 * @time 2020/5/7
 */
public interface ClusterService {

    /**
     * 用于通知新的节点加入。消息发送者通知接收者加入到当前集群，meet消息通信正常完成后，接收节点会加入到集群中兵进行周期性的ping，pong消息交换。
     *
     * @author jm008783
     * @param: [pingCommand]
     * @return: com.xiaoa.gossip.cluster.command.PongCommand
     **/
    PingCommand meet(PingCommand pingCommand);

    /**
     * 集群内交换最频繁的消息，集群内每个节点每秒向多个其他节点发送ping消息，用于检测节点是否在线和交换彼此状态信息。ping消息发送封装了自身节点和部分其他节点的状态数据。
     *
     * @author jm008783
     * @param: [pingCommand]
     * @return: com.xiaoa.gossip.cluster.command.PongCommand
     **/
    PingCommand ping(PingCommand pingCommand);

    /**
     * 当节点判定集群内另一个节点下线时，会向集群内广播一个fail消息，其他节点接收到fail消息之后把对应节点更新为下线状态。
     *
     * @author jm008783
     * @param: [pingCommand]
     * @return: com.xiaoa.gossip.cluster.command.PongCommand
     **/
    PingCommand fail(PingCommand pingCommand);

    /**
     * 添加至集群
     *
     * @author jm008783
     * @param: [nodeIp, port]
     * @return: boolean
     **/
    boolean addToCluster(String nodeIp, int port);

    /**
     * 处理pongCommand信息
     *
     * @author jm008783
     * @param: [pongCommand]
     * @return: void
     **/
    void doPongHandle(PingCommand pongCommand);

    /**
     *  像邻居发送ping信息
     * @author jm008783
     * @param: []
     * @return: void
     **/
    void doPingToNeighbor();

    /**
     *当前节点状态
     **/
    public List<PingNodeState> noteList();

    /**
     *  ping 失败时调用
     * @author jm008783
     * @param: [pingNodeState]
     * @return: void
     **/
    public void doPingFail(PingNodeState pingNodeState);

    /**
     *  更新最后ping时间
     * @author jm008783
     * @param: [noteId]
     * @return: void
     **/
    public  void updatePingLastTime(String noteId);

    /**
     *  更新节点状态
     * @author jm008783
     * @param: [nodeState, pingCommand]
     * @return: void
     **/
    public void addOrUpdateNode(PingNodeState nodeState, NodeState pingCommand);

    /**
     *  根据节点id 获取节点
     * @author jm008783
     * @param: [id]
     * @return: com.xiaoa.gossip.cluster.command.NodeState
     **/
    public NodeState getNodeState(String id);


}
